package com.woniuxy.config.websocket;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.service.UserService;
import com.woniuxy.service.impl.UserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
@ServerEndpoint("/websocket/{userId}/{username}/{campId}/{campname}")
public class WebSocketServer {

    private UserService userService ;

    private static ApplicationContext applicationContext;

    public static void setApplicationContext(ApplicationContext context) {
        applicationContext = context;
    }

    /**
     *  与某个客户端的连接对话，需要通过它来给客户端发送消息
     */
    private Session session;

    /**
     * 标识当前连接频道名
     */
    private String name;

    private String userKey;
    /**
     *  用于存所有的连接服务的客户端，这个对象存储是安全的
     */
    private static ConcurrentHashMap<String,HashMap<String,WebSocketServer>> webSocketSet = new ConcurrentHashMap<>();


    @OnOpen
    public void OnOpen(Session session, @PathParam(value = "userId") Integer userId,@PathParam(value = "campId") Integer campId,@PathParam(value = "username") String username,@PathParam(value = "campname") String campname) throws JsonProcessingException {
        this.session = session;
        this.name = campname + "#" + campId;
        String userKey = username + "#" + userId;
        this.userKey = userKey;

        //根据营地id区分聊天频道
        if(webSocketSet != null && webSocketSet.containsKey(name)){
            webSocketSet.get(name).put(this.userKey,this);
        }else{
            HashMap<String, WebSocketServer> groupMap = new HashMap<>();
            groupMap.put(userKey,this);
            webSocketSet.put(name,groupMap);
        }

        Set<Map.Entry<String, HashMap<String, WebSocketServer>>> entries = webSocketSet.entrySet();
        int count = 0;
        for(Map.Entry<String, HashMap<String, WebSocketServer>> mapEntry:entries){
            count += mapEntry.getValue().size();
        }
        log.info("总人数为：={}",count);
        log.info("{}聊天室连接成功，当前连接人数为：={}",campname,webSocketSet.get(name).size());
    }


    @OnClose
    public void OnClose(){
        webSocketSet.get(this.name).remove(this.userKey);
        if(webSocketSet.get(this.name).size() == 0){
            webSocketSet.remove(this.name);
        }
        log.info("[WebSocket] 退出成功，当前连接人数为：={}",webSocketSet.size());
    }

    @OnMessage
    public void OnMessage(String message) throws JsonProcessingException {
        log.info("[WebSocket] 收到消息：{}",message);
        ObjectMapper objectMapper = new ObjectMapper();
        HashMap<String, Object> map = new HashMap<>();
        map = objectMapper.readValue(message,map.getClass());
        Object type = ((Map<String, Object>) map.get("msg")).get("type");
        if(map.get("type").equals("user") && type.equals("text")){
            String text = (String) ((Map<String, Object>)((Map<String, Object>) map.get("msg")).get("content")).get("text");
            text = text.substring(text.indexOf(";\">")+3,text.indexOf("</div>"));
            //判断是否需要指定发送，具体规则自定义
            if(text.indexOf("@") == 0 && message.indexOf(":") > 1 && message.indexOf(":") <= 12){
                String name = text.substring(1,message.indexOf(":"));
                AppointSending(name,message);
            }else{
                GroupSending(message,false);
            }
        }



    }

    /**
     * 群发
     * @param message
     * @Param flag:表示是否发送给自己
     */
    public void GroupSending(String message ,boolean flag) throws JsonProcessingException {
        String camp = getCamp(message);
        String user = getUser(message);

        for (String name : webSocketSet.get(camp).keySet()){
            System.out.println(name);
            try {
                if(flag){
                    webSocketSet.get(camp).get(name).session.getBasicRemote().sendText(message);
                }else{
                    System.out.println(!user.equals(name));
                    if(!user.equals(name)){
                        webSocketSet.get(camp).get(name).session.getBasicRemote().sendText(message);
                    }
                }

            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    private String getCamp(String message) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        HashMap<String, Object> map = new HashMap<>();
        map = objectMapper.readValue(message,map.getClass());
        Map<String,Object> user = (Map<String, Object>) ((Map<String,Object>)(Map<String,Object>)map.get("msg")).get("user");
        return user.get("campname") +"#" + user.get("campId");
    }
    private String getUser(String message) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        HashMap<String, Object> map = new HashMap<>();
        map = objectMapper.readValue(message,map.getClass());
        Map<String,Object> user = (Map<String, Object>) ((Map<String,Object>)(Map<String,Object>)map.get("msg")).get("user");
        return user.get("username") +"#" + user.get("userId");
    }

    /**
     * 指定发送
     * @param name
     * @param message
     */
    public void AppointSending(String name,String message) throws JsonProcessingException {
        String camp = getCamp(message);
        try {
            webSocketSet.get(camp).get(name).session.getBasicRemote().sendText(message);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
